package z.nat;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VncProxyClient extends ChannelInboundHandlerAdapter {

	private static final Logger logger = LoggerFactory.getLogger(VncProxyClient.class);

	private Channel vncChannel;

	private final Channel wsChannel;

	public Channel getVncChannel() {
		return vncChannel;
	}

	VncProxyClient(ChannelHandlerContext ctx, String vncHost, int vncPort) {
		this.wsChannel = ctx.channel();

		logger.info("正在连接本地VNC服务: {}:{}", vncHost, vncPort);

		Bootstrap bootstrap = new Bootstrap()
				.group(WebSocketClient.eventLoopGroup)
				.channel(NioSocketChannel.class)
				.option(ChannelOption.SO_KEEPALIVE, true)
				.handler(new ChannelInitializer<SocketChannel>() {
					@Override
					protected void initChannel(SocketChannel ch) {
						ch.pipeline().addLast(VncProxyClient.this);
					}
				});

		// 连接本地VNC服务
		bootstrap.connect(vncHost, vncPort).addListener((ChannelFutureListener) future -> {
			if (future.isSuccess()) {
				vncChannel = future.channel();
				logger.info("本地VNC服务连接成功");
			} else {
				logger.error("无法连接到本地VNC服务", future.cause());
				ctx.writeAndFlush(new TextWebSocketFrame("ERROR:无法连接到本地VNC服务"));
			}
		});
	}

	/**
	 * 关闭VNC连接
	 */
	public void closeVncConnection() {
		if (vncChannel == null) return;
		vncChannel.close();
		logger.info("本地VNC连接已关闭");
	}


	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		if (wsChannel != null && wsChannel.isActive()) {
			if (msg instanceof ByteBuf) {
				ByteBuf buf = (ByteBuf)msg;
				logger.debug("转发本地VNC数据到服务端，长度: {}", buf.readableBytes());

				// 将VNC数据转发到WebSocket连接
				wsChannel.writeAndFlush(new BinaryWebSocketFrame(buf.retain()));
			}
		}
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) {
		logger.info("本地VNC连接断开");
		ctx.close();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		logger.error("本地VNC连接异常", cause);
		ctx.close();
	}

}
